#include "gnfindpaththread.h"
#include <QDir>

CNS_INIT(GnFindPathThread)
CNS_REGISTER_CNS_COM_FACTORY2(GnFindPathThread, CnsComponent)
CNS_INIT_END

GnFindPathThread::GnFindPathThread()
{

}

GnFindPathThread::~GnFindPathThread()
{
}

SysGnFindPathThread::SysGnFindPathThread()
{

}

void SysGnFindPathThread::f_initDbQueryThread(CnsComponentPtr com, QVariantHash& props, QScopedPointer<QThread>& thread)
{
    GnFindPathThreadPtr threadCom = com.staticCast<GnFindPathThread>();
    threadCom->setProps(props);
    QVariantHash v;
    v["method"] = "emitPushFilePaths";
    v["thread_com"] = QVariant::fromValue(threadCom);
    com->exec("startTimer", Q_ARG(const QVariantHash&, v));
    com->moveToThread(thread.data());
    connect(threadCom->getWorkThread().data(), &QThread::started, com.data(), [this,com,threadCom]()
    {
        QString dbID;
        com->exec("query", Q_ARG(QString &, dbID), QStringList(), Q_ARG(QVariantHash&, threadCom->getProps()));

//        stop(com);
    }, Qt::AutoConnection);

}

void SysGnFindPathThread::stop(CnsComponentPtr com)
{
    GnFindPathThread* thread = static_cast<GnFindPathThread*>(com.data());
    thread->getWorkThread()->quit();
    thread->setDead(true);
    thread->exec("stopTimer");
    if(thread->isForceStop()){
        return;
    }
    emit thread->dbQueryThreadFinished(com);
}

void SysGnFindPathThread::getFilterFile(GnFindPathThread* filterFilePaths, QString path, QString relativePath, const QString &filter)
{
    PathFilesInfo& pathFiles = filterFilePaths->getFilterFilePaths()[relativePath];
    if(pathFiles._status & FilesInfoStatus::FINISH_PATH)
        return;
    QDir dir(path);
    bool hasFile = false;
    QFileInfoList l = dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot | QDir::NoSymLinks, QDir::Name);
    for(QFileInfoList::iterator it = l.begin(); it != l.end(); it ++)
    {
        if(it->isFile())
        {
            if(it->fileName().contains(filter))
            {
                QWriteLocker(&filterFilePaths->getReadWriteLock());
                filterFilePaths->getFilterFilePaths()[relativePath]._files += it->fileName() +';';
                hasFile = true;
            }
        } else if(it->isDir())
        {
            getFilterFile(filterFilePaths, path+ it->fileName() +'/', relativePath + it->fileName() +'/', filter);
        }
    }
    if(hasFile)
        filterFilePaths->getFilterFilePaths()[relativePath]._status |= FilesInfoStatus::FINISH_PATH;
}

bool SysGnFindPathThread::f_query(CnsComponentPtr com, QString &dbID, QVariantHash &props)
{
    const QString &filter = props["filter"].toString();
    GnFindPathThread* thread = static_cast<GnFindPathThread*>(com.data());
    getFilterFile(thread, props["filesDirectory"].toString(), "/", filter);
    if(thread->getFilterFilePaths().find("/") == thread->getFilterFilePaths().end()){
        QWriteLocker(&thread->getReadWriteLock());
        thread->getFilterFilePaths()["/"]._files = ';';
        thread->getFilterFilePaths()["/"]._status |= FilesInfoStatus::FINISH_PATH;
    }
    return true;
}
